program main

    use common_info
    use space_manager
    use dynamic_quantities, only:    &
        np => num_parcel,            &
        nq => num_quantity,          &
        x => location,               &
        q => quantities,             &
        dynamic_quantities_init,     &
        folder_name => module_name,  &
        coordinate_name,             &
        quantities_name
    use message
    use string
    use file_io
    use run_manager

    implicit none

    integer, allocatable :: nx(:)
    real, allocatable :: dx(:)
    integer :: i, j, k
    integer, allocatable :: o(:)
    logical :: random
    real :: r
    integer :: temp1, temp2
    real :: temp3
    character(20) :: namelist_file
    character(100) :: msg, str
    logical :: alive

    random = .false.

    ! parsing command line arguments
    call get_command_argument(1, namelist_file)
    if(namelist_file == "") then
        call message_show(ERROR_MSG, &
            "gen_init_data",         &
            "main",                  &
            "namelist is needed")
        stop
    end if
    inquire(file=namelist_file, exist=alive)
    if(alive == .false.) then
        msg = "<namelist> file """ &
          // trim(namelist_file)   &  
          // """ does not exist"
        call message_show(ERROR_MSG, &
            "gen_init_data", "main", msg)
        stop
    end if

    call common_info_init(namelist_file)

    call space_manager_init(namelist_file)

    call dynamic_quantities_init(namelist_file)

    allocate(nx(num_dim))
    allocate(dx(num_dim))

    do i = 1, num_dim
        call get_command_argument(i+1, str)
        if(str == "") then
            call string_from_integer(num_dim, str)
            msg = "no dimension size inputted, " &
                // "you should input " &
                // trim(str) // " numbers"
            call message_show(ERROR_MSG, &
                "gen_init_data", "main", msg)
            stop
        end if
        read(str, "(i)") nx(i)
    end do

    dx = (boundary(2,:)-boundary(1,:))/nx

    ! generate coordinates
    allocate(o(num_dim))
    do j = 1, np
        temp1 = j
        do i = num_dim, 2, -1
            temp2 = 1
            do k = 1, i-1
                temp2 = temp2*nx(k)
            end do
            o(i) = int((temp1-1)/temp2)+1
            temp1 = mod(temp1, temp2)
        end do
        if(temp1 == 0) then
            o(1) = nx(1)
        else
            o(1) = temp1
        end if
        do i = 1, num_dim
            if(random) then
                call random_number(r)
                if(o(i) == 1) r = abs(r)
                if(o(i) == nx(i)) r = -abs(r)
                x(i,j) = boundary(1,i)+(o(i)-1)*dx(i)+r*dx(i)/nx(i)
            else
                x(i,j) = boundary(1,i)+(o(i)-1)*dx(i)
            end if
        end do
    end do

    ! generate dynamic quantities
    do j = 1, np
        ! height
        temp3 = 0.0
        do i = 1, num_dim
            temp3 = temp3+(x(i,j)-(boundary(2,i)-boundary(1,i))/2)**2
        end do
        temp3 = -100*temp3
        q(j,1) = 0.01*exp(temp3)
        ! wind
        q(j,2:nq) = 0.0
    end do

    ! output
    call file_io_create_output_file(input_file)
    call file_io_create_data_folder(input_file, folder_name)
    do i = 1, num_dim
        call file_io_create_data_card(input_file, folder_name,  &
            coordinate_name(i))
        call file_io_output("initial", input_file, folder_name, &
            coordinate_name(i), x(i,:), 1, (/np/))
    end do
    do i = 1, nq
        call file_io_create_data_card(input_file, folder_name,  &
            quantities_name(i))
        call file_io_output("initial", input_file, folder_name, &
            quantities_name(i), q(:,i), 1, (/np/))
    end do

    msg = "Initial data file """ // trim(input_file) &
        // """ is generated"
    call message_show(NOTICE_MSG, "gen_init_data", "main", msg)

    call run_manager_end_run

    stop
end program main
